// -----------------------------------------------------------------------
//  <copyright file="GetRoleResourceNodeQuery.cs" company="LiuliuSoft">
//      Copyright (c) 2025 66SOFT. All rights reserved.
//  </copyright>
//  <site>https://ifs.66soft.net</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2025-10-23 16:10</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Authorization.Domain.Specs;


namespace DaprPlus.Authorization.Application.Queries;

/// <summary>
/// 获取用于分配角色权限的资源列表查询
/// </summary>
[AuthConfig(typeof(Resource), ResourceAccessType.RoleLimit, "GetRoleResourceNode")]
public class GetRoleResourceNodeQuery : SingleQuery<List<ResourceNode>>
{
    /// <summary>
    /// 获取或设置 角色ID
    /// </summary>
    public long RoleId { get; set; }
}

/// <summary>
/// 获取用于分配角色权限的资源列表查询处理器
/// </summary>
public class GetRoleResourceNodeQueryHandler(IServiceProvider provider)
    : IRequestHandler<GetRoleResourceNodeQuery, List<ResourceNode>>
{
    public async Task<List<ResourceNode>> Handle(GetRoleResourceNodeQuery request, CancellationToken cancellationToken)
    {
        // 获取当前服务名称
        var serviceName = provider.GetServiceName();
        var resourceSpec = new ResourceByServiceNameSpec(serviceName)
            .And(new ResourceAllowedOperationsNotNullSpec());

        // 执行查询获取资源列表
        var resourceRepository = provider.GetQueryRepository<Resource>();
        var resources = await resourceRepository.GetAllAsync(resourceSpec, cancellationToken);

        // 查询角色资源分配信息
        var roleResourceRepository = provider.GetQueryRepository<RoleResource>();
        var roleResourceSpec = new RoleResourceByRoleIdSpec(request.RoleId);
        var roleResources = await roleResourceRepository.GetAllAsync(roleResourceSpec, cancellationToken);

        // 创建资源ID到角色资源的映射字典，用于快速查找
        var roleResourceDict = roleResources.ToDictionary(rr => rr.ResourceId, rr => rr);

        // 将资源列表转换为ResourceTreeNode列表，并标记选中状态
        var nodes = resources.Select(r =>
        {
            var node = new ResourceNode
            {
                Id = r.Id,
                Name = r.Name,
                Code = r.Code,
                Description = r.Description,
                Type = r.Type,
                AllowedOperations = r.GetAllowedOperations().Where(m => m.AccessType == ResourceAccessType.RoleLimit)
                    .ToArray()
            };

            // 如果在角色资源中找到对应的资源，则标记为选中并设置操作列表
            if (roleResourceDict.TryGetValue(r.Id, out var roleResource))
            {
                node.IsSelected = true;
                node.Operations = roleResource.GetOperations();
            }

            return node;
        }).ToList();

        return nodes;
    }
}